package scheduler

import "fmt"

type Engine interface {
	Run()
	createWorker(in chan string,out chan string,scheduler Scheduler)
}
type CurrentEngine struct {
	//调度器
	Scheduler Scheduler
	//工人数量
	WorkerCount int
	Processor Processor
}
type Processor func(string) (string, error)


func (c *CurrentEngine) createWorker(in chan string, out chan string, scheduler Scheduler) {
	//三个参数的含义
	//in chan string 用于 scheduler传输数据给worker进行处理
	//out chan string 用于worker处理完数据后将数据返回给Engine
	//scheduler Scheduler 当worker处理完成之后，
	//调用scheduler.WorkerReady将自己放进scheduler的WorkerChan中去
	go func() {
		for{
			scheduler.WorkerReady(in)
			//从in中获取请求数据
			request := <-in
			//调用Engine里的处理函数进行处理
			result, e := c.Processor(request)
			if e != nil{
				//不进行处理，进行下一个请求处理
			}
			//将结果传输出去
			out <- result
		}
	}()

}

func (c *CurrentEngine) Run(requests ...string) {
	//启动Scheduler
	c.Scheduler.Run()
	//out用于接收处理完的结果
	out := make(chan string)

	//启动多个Worker
	for i:=0;i<c.WorkerCount;i++{
		c.createWorker(c.Scheduler.WorkerChan(),out,c.Scheduler)
	}

	//提交任务
	for _,request := range requests{
		c.Scheduler.Submit(request)
	}

	//从out里取出数据
	i := 0
	for{
		result:= <- out
		fmt.Print(result)
		//这里如果是一个爬虫的话，就会继续讲result中的某些数据取出，再次投进Scheduler中给worker进行处理
		//这里我假装从result中获取到了新的request
		newRequests := make([]string,10)
		for k:=0;k<10;k++{
			newRequests = append(newRequests,fmt.Sprint(result,i))
		}
		//将新的Request放进Scheduler中去
		for _,request := range newRequests{
			c.Scheduler.Submit(request)
		}
	}
}



